package com.ecomm.util.web.context;

import com.ecomm.util.Logger;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.apache.commons.logging.Log;

import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;
import java.lang.reflect.Field;

import com.ecomm.util.SpringUtil;

/**
 * Created by IntelliJ IDEA.
 * User: Gavin
 * Date: 2007-7-1
 * Time: 12:04:43
 * To change this template use File | Settings | File Templates.
 */
public class ContextLoaderListener implements ServletContextListener {
    private static final Log log = Logger.getLog(ContextLoaderListener.class);
	private ContextLoader contextLoader;


	/**
	 * Initialize the root web application context.
	 */
	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		this.contextLoader.initWebApplicationContext(event.getServletContext());

        WebApplicationContext context = null;
        try{
            Field field = ContextLoader.class.getDeclaredField("context");
            boolean isAccess = field.isAccessible();
            if(!isAccess){
                field.setAccessible(true);
            }
            context = (WebApplicationContext)field.get(contextLoader);
            field.setAccessible(isAccess);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        setCtx(context);
        if(log.isInfoEnabled()){
            log.info("初始化SpringUtil context......");
        }
    }

	/**
	 * Create the ContextLoader to use. Can be overridden in subclasses.
	 * @return the new ContextLoader
	 */
	protected ContextLoader createContextLoader() {
		return new ContextLoader();
	}

	/**
	 * Return the ContextLoader used by this listener.
	 */
	public ContextLoader getContextLoader() {
		return contextLoader;
	}


	/**
	 * Close the root web application context.
	 */
	public void contextDestroyed(ServletContextEvent event) {
		if (this.contextLoader != null) {
			this.contextLoader.closeWebApplicationContext(event.getServletContext());
		}
        setCtx(null);
        if(log.isInfoEnabled()){
            log.info("销毁context......");
        }
    }

    private void setCtx(WebApplicationContext context){
        try{
            Field ctx = SpringUtil.class.getDeclaredField("ctx");
            boolean isAccess = ctx.isAccessible();
            if(!isAccess){
                ctx.setAccessible(true);
            }
            ctx.set(SpringUtil.class,context);
            ctx.setAccessible(isAccess);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

